// ============================================================================
// Implementation file for Myclnt
//
// Solution for CPSC 4780 Fall 2010 Group Project
// Fei Wang
// April 8, 2011
//
// Mysvc provide client stub functions
// ===========================================================================
#include "Myclnt.h"
#include "ClientSocket.h"
#include "SocketException.h"
#include <string>
#include <sstream>
using namespace std;


//================================================================================================
// look up service info in the portmapper
// if not success return NULL
//================================================================================================
CLIENT * my_clnt_create(const int & prog)
{
   CLIENT * var = NULL;
   ClientSocket *client_socket = new ClientSocket("localhost",10111);
   try{  
      string s_prog = "";
      stringstream progstream;
      progstream << prog;
      progstream >> s_prog;
      clntsock_send("look up",client_socket);
      clntsock_send( s_prog,client_socket);
      string feedback = "";
      clntsock_receive(feedback,client_socket);
      string s_host = "";
      string s_port = "";
      // if found service
      if(feedback == "Found")
      {
        var = new CLIENT;
        clntsock_receive(s_host,client_socket);
        clntsock_receive(s_port,client_socket);
        var -> host = s_host;
        int port;
        stringstream portstream;
        portstream << s_port;
        portstream >> port;
        var -> port = port;
      }    
   }    
   catch(SocketException& e){
      std::cout << "Exception was caught:" << e.description() << "\n";
   }
   delete client_socket;
   client_socket = NULL;
   return var;
}

//================================================================================================
// this function do the remote call
// if not success return false
//================================================================================================
bool my_clnt_call(CLIENT * rh,int proc,bool (*xdr_func_arg)(XDR *,char *,int),char * argp,bool (*xdr_func_res)(XDR *,char *,int),char * clnt_res)
{
   
   bool rev = true;
   ClientSocket * prc_clnt_socket = new ClientSocket(rh->host,rh->port);
   try
    {
       XDR arg;
       stringstream stream;
       string s_proc = "";
       stream << proc;
       stream >> s_proc;
       // convert datat to xdr and send to server
       if((*xdr_func_arg)(&arg,argp,1))
       {
          clntsock_send( s_proc,prc_clnt_socket);
          clntsock_send( arg,prc_clnt_socket);
          
       }
       else
       {
          rev = false;
          return rev;
       }
       // get reply from server
       XDR res = "";
       clntsock_receive(res,prc_clnt_socket);
       // trans back from XDR
       if(!(*xdr_func_res)(&res,clnt_res,2));
       {
          rev = false;
          return rev;
       }
      
    }
   catch(SocketException& e){
      std::cout << "Exception was caught:" << e.description() << "\n";
   }
   delete prc_clnt_socket;
   prc_clnt_socket = NULL;
   return rev;
   
}

